#include "serialportdriver.h"
#include <QSerialPort>
#include <QSerialPortInfo>
#include<QTimer>
SerialPortDriver *SerialPortDriver::obj = nullptr;
SerialPortDriver::SerialPortDriver(QObject *parent) : QObject(parent)
  ,serial(new QSerialPort)//初始化定义的serialport类的
  ,sendTimer(new QTimer)
{
serial->setDataBits(QSerialPort::Data8);
serial->setStopBits(QSerialPort::OneStop);
serial->setParity(QSerialPort::NoParity);
serial->setFlowControl(QSerialPort::NoFlowControl);
connect(serial,&QSerialPort::readyRead,this,&SerialPortDriver::serialPortReadyReadSlot);//绑定发来的数据的信号与槽函数
connect(sendTimer,&QTimer::timeout,this,&SerialPortDriver::sendTimerTimeoutSlot);//绑定定时器的信号和槽函数
sendTimer->start(1500);//启动定时器
}

SerialPortDriver *SerialPortDriver::getObject()
{
if(obj==nullptr)

    obj=new SerialPortDriver;
return obj;
}

QStringList SerialPortDriver::serialPortGetAveList()
{ QStringList list;//foreach循环中的访问变量定义成引用而不定义成对象是为了节省内存的开销
    foreach (const QSerialPortInfo &obj, QSerialPortInfo::availablePorts()) {
      list.append(obj.portName());
    }
    return list;
}

bool SerialPortDriver::serialPortOpen()
{
    if(serial->isOpen())
        serial->close();//如果已经打开了串口，就将之前打开的串口关闭
serial->setPortName("COM10");//设置默认端口号为COM10
serial->setBaudRate(57600);//设置默认波特率为57600
bool ok;
ok=serial->open(QSerialPort::ReadWrite);//打开串口
return ok;
}

bool SerialPortDriver::serialPortOpen(QString portName)
{ if(serial->isOpen())
        serial->close();//如果已经打开了串口，就将之前打开的串口关闭
    serial->setPortName(portName);
    serial->setBaudRate(57600);//设置默认波特率为57600
    bool ok;
    ok=serial->open(QSerialPort::ReadWrite);//打开串口
    return ok;

}

bool SerialPortDriver::serialPortOpen(QString portName, qint32 baudRate)
{ if(serial->isOpen())
        serial->close();//如果已经打开了串口，就将之前打开的串口关闭
    serial->setPortName(portName);
    serial->setBaudRate(baudRate);
    bool ok;
    ok=serial->open(QSerialPort::ReadWrite);//打开串口
    return ok;

}

void SerialPortDriver::serialPortClose()
{
if(serial->isOpen())//如果串口已经打开就关闭，如果已经关闭，就不需要重复操作而浪费资源
    serial->close();
}

bool SerialPortDriver::setPortName(QString portName)
{
if(serialPortIsOpen())
    return false;
serial->setPortName(portName);
return true;

}

bool SerialPortDriver::setBaudRate(qint32 baudRate)
{
    if(serialPortIsOpen())
        return false;
    serial->setBaudRate(baudRate);
    return true;
}

bool SerialPortDriver::setDataBits(int dataBits)
{
    if(serialPortIsOpen())
        return false;
    if(dataBits < 5 || dataBits > 8)
        return false;
    serial->setDataBits(static_cast<QSerialPort::DataBits>(dataBits));
    return true;
}

bool SerialPortDriver::setStopBits(int stopBits)
{
    if(serialPortIsOpen())
        return false;
    if(stopBits < 1 ||stopBits >3)
        return false;
    serial->setStopBits(static_cast<QSerialPort::StopBits>(stopBits));
    return true;
}

bool SerialPortDriver::serialPortIsOpen()
{
return serial->isOpen();
}

bool SerialPortDriver::serialPortWrite(const QByteArray &data,int pro)
{
if(!serialPortIsOpen())
    return false;
if(pro == 1)
    sendList.insert(0,data);//优先级高的插入到第一个
else {
    sendList.append(data);//优先级低的插入到队尾
}
return  true;
}

void SerialPortDriver::serialPortReadyReadSlot()//接收到数据的槽函数
{
  QByteArray data;
  data = serial->readAll();//data不一定是完整的一帧，串口发送的数据是比较慢的
  emit serialPortReadData(data);//接受到之后，将数据传给信号
}

void SerialPortDriver::sendTimerTimeoutSlot()
{

if(sendList.isEmpty())//如果消息队列为空，那么就不发送
    return;
if(!serialPortIsOpen())//串口没有大开也不发送
    return;
QByteArray data =sendList.first();//多线程并发时准备成员变量锁
qint64 len = serial->write(data);
bool ok = len == data.length() ? true :false;//如果返回TRUE，说明发送成功了
if(ok)
    sendList.removeFirst();//就把已经发送的删掉
}





